package com.ficv.findme;

import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.StrictMode;
import android.util.Log;

public class GpsService  extends Service {
		   
		  public static final int NOTIFICATION_ID = 101;

		public static final String MiService = GpsService.class.getSimpleName();
		  
		  LocationManager locationManager;
		  Handler handlerNot;
		  Handler handlerGps;
		  
		  private Timer timerGps;
		  private Timer timerNot;
		  
		  private long cont=1;
		  private long intentos=0;
		  
		//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
			
		  //private TimerTask updateTask = new MyTimerTask();
		  
		  private class MyTimerTask extends TimerTask {
		    @Override
		    public void run() {
		    	
		  //  	String data=prefs.getString("com.ficv.findme.data","dddd"); 
			String data=JavascriptFacade.DATA;	
		      Log.i(MiService, "Timer task doing work with data: " + data);
		      synchronized (serviceLock) {
				  
		    	  handlerGps.post(new Runnable() { // This thread runs in the UI
	                    @Override
	                    public void run() {  Log.i(MiService, "REQUEST UPDATES: ");
	                    	locationManager.removeUpdates(listener);
	                    	resting=false;
	                    	restingTime=new Date();
	                    	locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
	     			                1000,          // 10-second interval.
	     			                15,             // 50 meters.
	     			                listener);
	                    }
	                });


		    	}
		    		
		    }

			
		  };
		
		  
		  private class MyNotificationTask extends TimerTask {
			    @Override
			    public void run() {
//			    	Looper.prepare();
			  //  	String data=prefs.getString("com.ficv.findme.data","dddd"); 
				String data=JavascriptFacade.DATA;	
			      Log.i(MiService, "Notification task doing work with data: " + data);
			      synchronized (serviceLock) {
					  
			    	  handlerNot.post(new Runnable() { // This thread runs in the UI
		                    @Override
		                    public void run() {  
		                    	Log.i(MiService, "REQUEST NOTIFICATION: ");
		                    	//GetNotification gNot= new GetNotification(getContentResolver());
		                    	//List<Peticiones> pets=gNot.doInBackground();	
		                    	try {
		                    			cancelGetLocation();
		                    			GetNotification getNot = new GetNotification(getContentResolver());
		                    			String [] strs = { "37.891", "-4.7997965","50"};
				                    	List<Contactos> pets=getNot.doInBackground(strs);
				                    	
//				                    	SendPosition sp= new SendPosition(getContentResolver(),getApplicationContext());
//
//				                    	sp.getUrl("testDEviceID", strs);
				                    		
				                    	if(pets!=null && pets.size()>0) {
				               	    	 	notifica();
				                    	}
				                    	Log.i(MiService, "mensajes: " + ((pets==null)?"null":pets.size()));
				                    	
//				                    	Looper.myLooper().quit();
				                    	
			          			 } catch(Throwable t) {
			        				  Log.e(MiService, t.getCause() + ": " + t.getMessage());
			        			  }

		                    }
		                });

		                    	//Looper.loop();
		                    	
		                    	
			    	}
			    		
			    }

				
		};
		
		  private boolean resting=true;
		  private Date restingTime = new Date();
		  private Location lastLocation=null;
		  
		  private final LocationListener listener = new LocationListener() {

			    @Override
			    public void onLocationChanged(Location location) {

			    	//if(isBetterLocation(location, lastLocation)) {
			    		lastLocation=location;
			    		
				    	try { Log.i(MiService, "LOCATION accuracy: " + location.getAccuracy());
				    		
				    		 //if(location.getAccuracy()<20 || intentos++ > 5) {
						    	  
						    	  //setNewPosition(location.getLatitude(),location.getLongitude(),location.getAccuracy());
						    	  SendPosition sp= new SendPosition(getContentResolver(),getApplicationContext());
								  sp.execute(String.valueOf(location.getLatitude()),String.valueOf(location.getLongitude()),String.valueOf(location.getAccuracy())); 
								  Log.i(MiService, "LOCATION sending: " + location.getLatitude() + "," + location.getLongitude());
						    	  
								  
								  dealWithLocation(location);
				    		 //}
				    	} catch(Throwable e) {
				    		Log.v("ERROR: ", e.getCause() + ": " + e.getMessage());
				       
				    	}
			    	//}
			    }

				@Override
				public void onProviderDisabled(String provider) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onProviderEnabled(String provider) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onStatusChanged(String provider, int status,
						Bundle extras) {
					// TODO Auto-generated method stub
					
				}
			    

		  };
		  
private final Object serviceLock = new Object();


	  
		  @Override
		  public IBinder onBind(Intent intent) {
		    // TODO Auto-generated method stub
		    return null;
		  }
		 
		  public void notifica2() {
			  	
			  try{
			  
			  	String ns = Context.NOTIFICATION_SERVICE;
	    		NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
	    		
	    		int icon = R.drawable.ic_launcher;
	    		CharSequence tickerText = "Mensajes en FindMe";
	    		long when = System.currentTimeMillis();

	    		Notification notification = new Notification(icon, tickerText, when);
	    		
	    		Context context = getApplicationContext();
	    		CharSequence contentTitle = "Mensajes en FindMe";
	    		CharSequence contentText="mensajes sin leer";
	    		Intent notificationIntent = new Intent(this, MainActivity.class);
	    		notificationIntent.putExtra("NotificationMessage", "mensajes sin leer");
	    		notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
	    		notification.flags |= Notification.FLAG_AUTO_CANCEL;

	    		PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);


	    		notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
	    			    		

	    		mNotificationManager.notify(NOTIFICATION_ID, notification);
			  } catch(Throwable t) {
				  Log.e(MiService, t.getCause() + ": " + t.getMessage());
			  }

		}
		  private void notifica() {
		        
			  String message="mensajes sin leer";
			  Context context = getApplicationContext();
			  
			  int icon = R.drawable.ic_launcher;
		        long when = System.currentTimeMillis();
		        NotificationManager notificationManager = (NotificationManager)
		                context.getSystemService(Context.NOTIFICATION_SERVICE);
		        Notification notification = new Notification(icon, message, when);

		        String title = context.getString(R.string.app_name);

		        Intent notificationIntent = new Intent(context, MainActivity.class);
		        // set intent so it does not start a new activity
		        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
		                Intent.FLAG_ACTIVITY_SINGLE_TOP);
		        PendingIntent intent =
		                PendingIntent.getActivity(context, 0, notificationIntent, 0);
		        notification.setLatestEventInfo(context, title, message, intent);
		        notification.flags |= Notification.FLAG_AUTO_CANCEL;

		        // Play default notification sound
		        notification.defaults |= Notification.DEFAULT_SOUND;

		        // Vibrate if vibrate is enabled
		        notification.defaults |= Notification.DEFAULT_VIBRATE;
		        notificationManager.notify(0, notification);      

		    }
		@Override
		  public void onCreate() {
		    super.onCreate();
		    Log.i(MiService, "Service creating");
		    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

		    StrictMode.setThreadPolicy(policy); 
		     
		    handlerNot = new Handler();
		    handlerGps = new Handler();
		    
		    locationManager =  (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);

	    	
		    timerGps = new Timer("gpsTimer");
		    timerGps.schedule(new MyTimerTask(), 1000L); //, 10 * 1000L);
		    
		    timerNot = new Timer("notificationTimer");
		    timerNot.schedule(new MyNotificationTask(), 1000L, 30 * 1000L);
		  }
		 
		  @Override
		  public void onDestroy() {
		    super.onDestroy();
		    
		    locationManager.removeUpdates(listener);
		    
		    Log.i(MiService, "Service destroying");
		     
		    timerGps.cancel();
		    timerGps = null;
		    timerNot.cancel();
		    timerNot = null;
		  }

		  


		  
//		  
//	  protected void setNewPosition(double lat, double lon, float precision) {
//			
//				try 
//				{
//
//					//String androidId=Secure.getString(getContentResolver(), Secure.ANDROID_ID);	
//					String androidId="172.30.49.27";
//					Date d = new Date();
//					String url = MainActivity.URL_BASE + "position?id=" + androidId + "&lat="+ lat + "&lon="+ lon + "&precision="+ precision + "&time=" + d.getTime();
//
//
//					HttpHeaders requestHeaders = new HttpHeaders();
//					List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
//					acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
//					requestHeaders.setAccept(acceptableMediaTypes);
//					
//					// Populate the headers in an HttpEntity object to use for the request
//					HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
//					
//					// Create a new RestTemplate instance
//					RestTemplate restTemplate = new RestTemplate();
//					
//					// Perform the HTTP GET request
//					ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
//					
//					// Return the list of states
//					String result  = responseEntity.getBody();
//
//					Log.v(MiService, url + ": " + result);
//				} 
//				catch(Exception e) 
//				{
//					Log.e("TAG", e.getMessage(), e);
//				} 
//
//			}   
//	
//	  
//	  protected List<Peticiones> getPeticiones() {
//			
//		  try 
//			{
//
//				String androidId=Secure.getString(getContentResolver(), Secure.ANDROID_ID);	
//				//String androidId="69d6d4731c4b6725";
//				Date d = new Date();
//				String url = MainActivity.URL_BASE + "getPeticiones?deviceId=" + androidId + "&time=" + d.getTime();
//
//				Log.v("GetNotification","url: " + url);
//				
//				HttpHeaders requestHeaders = new HttpHeaders();
//				List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
//				acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
//				requestHeaders.setAccept(acceptableMediaTypes);
//				
//				// Populate the headers in an HttpEntity object to use for the request
//				HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
//				
//				// Create a new RestTemplate instance
//				RestTemplate restTemplate = new RestTemplate();
//				restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
//				// Perform the HTTP GET request
//				Log.v("GetNotification","request: " + restTemplate);
//				ResponseEntity<Peticiones[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Peticiones[].class);
//				
//				
//				Log.v("GetNotification","result: " + responseEntity);
//
//				return Arrays.asList(responseEntity.getBody());
//
//			} 
//			catch(Throwable e) 
//			{
//				Log.e("TAG", e.getMessage(), e);
//				return null;
//			} 
//	  }	  
		   
private static final int TWO_MINUTES = 1000 * 60 * 2;

/** Determines whether one Location reading is better than the current Location fix
  * @param location  The new Location that you want to evaluate
  * @param currentBestLocation  The current Location fix, to which you want to compare the new one
  */
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
    if (currentBestLocation == null) {
        // A new location is always better than no location
        return true;
    }

    // Check whether the new location fix is newer or older
    long timeDelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    boolean isNewer = timeDelta > 0;

    // If it's been more than two minutes since the current location, use the new location
    // because the user has likely moved
    if (isSignificantlyNewer) {
        return true;
    // If the new location is more than two minutes older, it must be worse
    } else if (isSignificantlyOlder) {
        return false;
    }

    // Check whether the new location fix is more or less accurate
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
    boolean isLessAccurate = accuracyDelta > 0;
    boolean isMoreAccurate = accuracyDelta < 0;
    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

    // Check if the old and new location are from the same provider
    boolean isFromSameProvider = isSameProvider(location.getProvider(),
            currentBestLocation.getProvider());

    // Determine location quality using a combination of timeliness and accuracy
    if (isMoreAccurate) {
        return true;
    } else if (isNewer && !isLessAccurate) {
        return true;
    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
        return true;
    }
    return false;
}

/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
    if (provider1 == null) {
      return provider2 == null;
    }
    return provider1.equals(provider2);
}

private void dealWithLocation(Location location) {
	if(location.getAccuracy()<100) {
		  renewLocationUpdates();
		  lastLocation=location;
	  }
}

private void cancelGetLocation() {

	  long last= restingTime.getTime();
	  long now= (new Date()).getTime();
		  
	  Log.v(GpsService.class.getSimpleName(), restingTime + "," + resting);
	  long delay=Long.parseLong(JavascriptFacade.DATA);
	  
	  	 if(!resting) {
			  
			  if(now-last>45000) {
				  Log.v(GpsService.class.getSimpleName(), "reiniciando gps atascado" );

				  renewLocationUpdates();
			  }
		  }
	  	 
	  	 else if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER ) && now-last > delay * 2) {
			  Log.v(GpsService.class.getSimpleName(), "reiniciando gps tras apagado" );
	  		 renewLocationUpdates();
	  	 }
			  
}

private void renewLocationUpdates() {
		timerGps.cancel();
	  locationManager.removeUpdates(listener);
	  resting=true;
	  timerGps=new Timer("gpsTimer");
	  
	  long delay=Long.parseLong(JavascriptFacade.DATA);
	  
	  Log.v(GpsService.class.getSimpleName(),"setting latency: " + delay);
	  
	  if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER )) {
		  timerGps.schedule(new MyTimerTask(), delay); // * cont);
		  Log.v(GpsService.class.getSimpleName(), "reiniciado gps" );
	  }
}


}


